import os
import re
import sys
from lxml import etree
from glob import glob

class Stat(object):
	def __init__(self, proto, *args, **kw):
		object.__init__(self, *args, **kw)
		self.name = proto[0]
		if len(proto) < 3:
			self.attr_key = self.name.capitalize()
		else:
			self.attr_key = proto[2]
		self.value = None



class StrStat(Stat):
	def __init__(self, proto, *args, **kw):
		Stat.__init__(self, proto, *args, **kw)
		self.value = ""

	def from_xml(self, el):
		self.value = el.attrib[self.attr_key]
	def print_it(self):
		print "{0} : {1}".format(self.name, self.value.encode("utf-8"))

class FltStat(Stat):
	def __init__(self, proto, *args, **kw):
		Stat.__init__(self, proto, *args, **kw)
		self.value = 0.0
		self.min = 0.0
		self.max = 100.0
		self.random = False

	def print_it(self):
		print "{0} : {1}".format(self.name, self.value)

	def from_xml(self, el):
		if el.tag == "Girl":
			unique_from_xml(self, el)
		else:
			generic_from_xml(self, el)

	def generic_from_xml(self, xml_girl):
		self.random = True
		self.lo_bound = xml_girl.get("Min")
		self.hi_bound = xml_girl.get("Max")

	def unique_from_xml(self, el):
		v = el.attrib[self.attr_key]
		if v.strip() == "":
			v = "0.0"
		try:
			self.value = float(v)
		except:
			print self.name,  ": '", v, "'"
			print sys.exc_info()[0]
			raise
	def print_it(self):
		print "{0} : {1}".format(self.name, self.value)


class IntStat(Stat):
	def __init__(self, proto, *args, **kw):
		Stat.__init__(self, proto, *args, **kw)
		self.value = 0
		self.random = False

	def from_xml(self, el):
		if el.tag == "Girl":
			self.value = int(el.attrib[self.attr_key])
		else:
			self.random = True
			self.lo_bound = el.get("Min")
			self.hi_bound = el.get("Max")
			
	def print_it(self):
		print "{0} : {1}".format(self.name, self.value)

_stat_templates = [
	[ "name", str ],
	[ "desc", str ],
	[ "charisma", float ],
	[ "happiness", float ],
	[ "libido", float ],
	[ "constitution", float ],
	[ "intelligence", float ],
	[ "confidence", float ],
	[ "mana", float ],
	[ "agility", float ],
	[ "fame", float ],
	[ "level", float ],
	[ "ask_price", float, "AskPrice" ],
	[ "house", float ],
	[ "exp", float ],
	[ "age", str ],
	[ "obedience", float ],
	[ "spirit", float ],
	[ "beauty", float ],
	[ "tiredness", float ],
	[ "health", float ],
	[ "pc_fear", float, "PCFear" ],
	[ "pc_love", float, "PCLove" ],
	[ "pc_hate", float, "PCHate" ],
	[ "anal", float ],
	[ "magic", float ],
	[ "bdsm", float, "BDSM" ],
	[ "normal_sex", float, "NormalSex" ],
	[ "beast", float, "Beastiality" ],
	[ "group", float ],
	[ "lesbian", float ],
	[ "service", float ],
	[ "strip", float ],
	[ "combat", float ],
	[ "gold", int ],
	[ "status", str ]
]

class GirlBase(object):
	def __init__(self, *args, **kw):
		object.__init__(self, *args, **kw)

		self.stats = {}
		self.xml_names = {}
		for st in _stat_templates:
			o = None
			if st[1] == str:
				o = StrStat(st)
			elif st[1] == int:
				o = IntStat(st)
			elif st[1] == float:
				o = FltStat(st)
			self.stats[o.name] = o
			self.xml_names[o.name] = o
		self.traits = []

class Trait(object):
	def __init__(self, *args, **kw):
		object.__init__(self, *args, **kw)
		self.name = ""
		self.random = False
		self.min = 100
		self.max = 100

	def from_xml(self, el):
		self.name = el.get("Name")
		s = el.get("Min")
		if s:
			self.min = int(s)
		s = el.get("Max")
		if s:
			self.max = int(s)
		if self.min != 100 or self.max != 100:
			self.random = True

class GirlTemplate(GirlBase):
	def __init__(self, *args, **kw):
		GirlBase.__init__(self, *args, **kw)
		self.stats = {}

	def from_xml(self, xml_girl):
		self.name = xml_girl.get("Name")
		self.desc = xml_girl.get("Desc")
		self.human = xml_girl.get("Human")
		self.catacomb = xml_girl.get("Catacomb")

		for el in xml_girl:
			if el.Tag == "Gold":
				self.xml_names["Gold"].from_xml(xml_girl)
				continue
			name = xml_girl.get("Name")
			if el.Tag in [ "Stat", "Skill" ]:
				self.xml_names[name].from_xml(xml_girl)

			for xml_trait in xml_girl:
				if xml_trait.tag != "Trait":
					continue
				t = Trait()
				t.from_xml(xml_trait)
				traits.append(t)

class Girl(GirlBase):
	def __init__(self, *args, **kw):
		GirlBase.__init__(self, *args, **kw)

	def from_xml(self, xml_girl):
		for stat in self.stats.itervalues():
			stat.from_xml(xml_girl)
		for trait in xml_girl:
			if trait.tag != "Trait":
				continue
			traits.append(trait.get("Name"))

	def print_it(self):
		for st in _stat_templates:
			st_name = st[0]

			self.stats[st_name].print_it()
		print ""

class GirlManager(object):
	def __init__(self, *args, **kw):
		object.__init__(self, *args, **kw)

		self.unique = []
		self.generic = []

	def scan(self):
		uni_files = glob("resources/characters/*.girlsx")
		gen_files = glob("resources/characters/*.rgirlsx")

		print "Generic Girls"
		for s in gen_files:
			self.read_generic(s)
		print ""

		print "Unique Girls"
		for s in uni_girls:
			self.read_unique(s)
		print ""

	def read_generic(self, file):
		print file, ":"
		girl = GirlTemplate()
		tree = etree.parse(file)
		root = tree.getroot()

		for xml_girl in root:
			girl.from_xml(xml_girl)
			girl.print_it()
			self.generics.append(girl)

	def read_unique(self, file):
		print file, ":"
		girl = Girl()
		tree = etree.parse(file)
		root = tree.getroot()

		for xml_girl in root:
			girl.from_xml(xml_girl)
			girl.print_it()
			self.uniques.append(girl)

	def random_unique(self, **kw):
		exes = kw.get("excluding", [])
		reqs = kw.get("requiring", [])
		reqs = kw.get("slave", None)
		reqs = kw.get("virgin", None)

		candidates = []

		for girl in self.uniques:
			if girl.has_trait(exes):
				continue
			if girl.lacks_trait(reqs):
				continue
			candidates.append(girl)
		return random.choice(candidates)
manager = GirlManager()
manager.scan()
